using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Weight.Base
{
    public  class ReflectHelper
    {

        /// <summary>
        /// 返回所有的字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static  IEnumerable<PropertyInfo> GetPropertyInfo<T>(T t)
        {
            if (t == null) return null;
            PropertyInfo[] propertys = t.GetType().GetProperties();
            return propertys;
        }

        /// <summary>
        /// 获取所有属性的名称
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static  IEnumerable<string> GetPropertyName<T>(T t)
        {
            IEnumerable<PropertyInfo> properties = GetPropertyInfo(t);
            List<string> propertyName = new List<string>();
            if(properties != null)
            {
                foreach(PropertyInfo item in properties)
                {
                    propertyName.Add(item.Name);
                }
            }

            return propertyName;
        }

        /// <summary>
        ///获取字段名称
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static string GetValueByName<T>(T t, string name)
        {
            string resVal = string.Empty;
            IEnumerable<PropertyInfo> propertys = GetPropertyInfo(t);
            foreach (var item in propertys)
            {
                if (item.Name == name)
                {
                    resVal = Convert.ToString(item.GetValue(t));
                    break;
                }
            }

            return resVal;
        }

        /// <summary>
        ///批量复制
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="dataMap"></param>
        /// <returns></returns>
        public static T SetValToEnity<T>(Dictionary<string,string> dataMap)
        {
            var  entity = Activator.CreateInstance(typeof(T));
            IEnumerable<PropertyInfo> properties = GetPropertyInfo(entity);
            if(properties  != null)
            {
                string pType = string.Empty;
                string val = string.Empty;
                foreach(var item in properties)
                {
                    pType = item.PropertyType.FullName;
                    if (dataMap.Keys.Contains(item.Name))
                    {
                        val = dataMap[item.Name];
                        if (pType == "System.String")
                        {
                            item.SetValue(entity, val);
                        }
                        else if(pType == "System.Boolean")
                        {
                            if(val == "1")
                            {
                                item.SetValue(entity, true);
                            }
                            else
                            {
                                item.SetValue(entity, false);
                            }
                        }
                        else if(pType== "System.Int32")
                        {
                            int?   nVal =   UtilityHelper.StrToInt(val);
                            if(nVal != null)
                            {
                                item.SetValue(entity, nVal);
                            }
                        }
                        else if(pType == "System.Decimal")
                        {
                            decimal? dVal = UtilityHelper.StrToDecimal(val);
                            if(dVal != null)
                            {
                                item.SetValue(entity, dVal);
                            }
                        }
                        else if(pType == "System.Double")
                        {
                            double? dVal = UtilityHelper.StrToDouble(val);
                            if (dVal != null)
                            {
                                item.SetValue(entity, dVal);
                            }
                        }

                    }
                }
            }
            return (T)entity;
        }

        /// <summary>
        /// 把Model转换为DataRow
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="mod"></param>
        /// <returns></returns>
        public static T ParseDictionaryToModel<T>(Dictionary<string, string> dict)
        {
            T obj = default(T);
            obj = Activator.CreateInstance<T>();

            //根据Key值设定 Columns
            foreach (KeyValuePair<string, string> item in dict)
            {
                try
                {
                    PropertyInfo prop = obj.GetType().GetProperty(item.Key);
                    if (prop == null) continue;
                    if (!string.IsNullOrEmpty(item.Value))
                    {
                        object value = item.Value;
                        //Nullable 获取Model类字段的真实类型
                        Type itemType = Nullable.GetUnderlyingType(prop.PropertyType) == null ? prop.PropertyType : Nullable.GetUnderlyingType(prop.PropertyType);
                        //根据Model类字段的真实类型进行转换
                        prop.SetValue(obj, Convert.ChangeType(value, itemType), null);
                    }
                }
                catch(Exception ex)
                {
                    continue;
                }
              

            }
            return obj;
        }

        /// <summary>
        /// 设置字段值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataMap"></param>
        /// <param name="entity"></param>
        public static Dictionary<string,string> ParseEntityToMap<T>(T entity)
        {
            Dictionary<string, string> fieldVal = new Dictionary<string, string>();
            IEnumerable<PropertyInfo> properties = GetPropertyInfo(entity);
            if (properties != null)
            {
                string pType = string.Empty;
                string val = string.Empty;
                foreach (var item in properties)
                {
                    pType = item.PropertyType.FullName;
                    if (pType == "System.String")
                    {
                        val = Convert.ToString( item.GetValue(entity));
                    }
                    else if (pType == "System.Boolean")
                    {
                        val = Convert.ToString(item.GetValue(entity));
                        if (val.ToLower() == "true")
                        {
                            val = "1";
                        }
                        else
                        {
                            val = "0";
                        }
                    }
                    else if (pType == "System.Int32")
                    {
                        val = Convert.ToString(item.GetValue(entity));
                    }
                    else if (pType == "System.Decimal")
                    {
                        val = Convert.ToString(item.GetValue(entity));
                    }
                    else if (pType == "System.Double")
                    {
                        val = Convert.ToString(item.GetValue(entity));
                    }
                    else if(pType == "System.Single")
                    {
                        val = Convert.ToString(item.GetValue(entity));
                    }
                    else
                    {
                        val = Convert.ToString(item.GetValue(entity));
                    }
                   
                    if(!fieldVal.Keys.Contains(item.Name))
                    {
                        fieldVal.Add(item.Name, val);
                    }
                }
            }
            return fieldVal;
        }
    }
}


